package com.zenithsun.common.util.encrypt;

import java.security.SecureRandom;
import java.util.Random;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.SecretKeyFactory;
import javax.crypto.SecretKey;
import javax.crypto.Cipher;

/**
 * DES加密介绍 DES是一种对称加密算法，所谓对称加密算法即：加密和解密使用相同密钥的算法。DES加密算法出自IBM的研究，
 * 后来被美国政府正式采用，之后开始广泛流传，但是近些年使用越来越少，因为DES使用56位密钥，以现代计算能力，
 * 24小时内即可被破解。虽然如此，在某些简单应用中，我们还是可以使用DES加密算法，本文简单讲解DES的JAVA实现 。
 * 注意：DES加密和解密过程中，密钥长度都必须是8的倍数
 * @author wanglei@enersun.com.cn
 */
public class DES {

	public DES() {

	}

	private static byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8 };
	private static String _keyType = "DES";
	private static String _keyType3 = "DES/CBC/PKCS5Padding";
	private static String _charEn = "UTF-8";

	/**
	 * 给出长度，生成指定长度的密码
	 * @param length (length为8的倍数)
	 * @return
	 */
	public static String CreatePassword(int length) {
		String passwordSource = "abcdefghijklmnopqrstuvwxyz1234567890";
		if (length % 8 != 0) {
			return null;
		}
		StringBuffer p = new StringBuffer();
		for (int i = 0; i < length; i++) {
			p.append(passwordSource.charAt(new Random().nextInt(passwordSource.length())));
		}
		return p.toString();
	}

	/**
	 * 加密（和IOS一致），推荐使用
	 * @param encryptString
	 * @param encryptKey
	 * @return
	 * @throws Exception
	 */
	public static String encryptDES(String encryptString, String encryptKey) throws Exception {
		IvParameterSpec zeroIv = new IvParameterSpec(iv);
		DESKeySpec desKey = new DESKeySpec(encryptKey.getBytes());
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(_keyType);
		SecretKey securekey = keyFactory.generateSecret(desKey);
		Cipher cipher = Cipher.getInstance(_keyType3);
		cipher.init(Cipher.ENCRYPT_MODE, securekey, zeroIv);
		byte[] encryptedData = cipher.doFinal(encryptString.getBytes(_charEn));
		return Base64.encode(encryptedData);
	}

	/**
	 * 解密（和IOS一致），推荐使用
	 * @param encryptString
	 * @param encryptKey
	 * @return
	 * @throws Exception
	 */
	public static String decryptDES(String encryptString, String encryptKey) throws Exception {
		byte[] src = Base64.decode(encryptString);
		IvParameterSpec zeroIv = new IvParameterSpec(iv);
		// 创建一个DESKeySpec对象
		DESKeySpec desKey = new DESKeySpec(encryptKey.getBytes(_charEn));
		// 创建一个密匙工厂
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(_keyType);
		// 将DESKeySpec对象转换成SecretKey对象
		SecretKey securekey = keyFactory.generateSecret(desKey);
		// Cipher对象实际完成解密操作
		Cipher cipher = Cipher.getInstance(_keyType3);
		// 用密匙初始化Cipher对象
		cipher.init(Cipher.DECRYPT_MODE, securekey, zeroIv);
		// 真正开始解密操作
		return new String(cipher.doFinal(src), _charEn);
	}

	/**
	 * 加密（不兼容IOS）
	 * @param datasource byte[]
	 * @param password String
	 * @return byte[]
	 */
	@Deprecated
	public static String encrypt(String datasource, String password) {
		try {
			SecureRandom random = new SecureRandom();
			DESKeySpec desKey = new DESKeySpec(password.getBytes());
			// 创建一个密匙工厂，然后用它把DESKeySpec转换成
			SecretKeyFactory keyFactory = SecretKeyFactory
					.getInstance(_keyType);
			SecretKey securekey = keyFactory.generateSecret(desKey);
			// Cipher对象实际完成加密操作
			Cipher cipher = Cipher.getInstance(_keyType);
			// 用密匙初始化Cipher对象
			cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
			// 现在，获取数据并加密
			// 正式执行加密操作
			return Base64.encode(cipher.doFinal(datasource.getBytes(_charEn)));
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 二进制转字符串
	 * @param b
	 * @return
	 */
	public static String byte2hex(byte[] b) {
		StringBuffer sb = new StringBuffer();
		String tmp = "";
		for (int i = 0; i < b.length; i++) {
			tmp = Integer.toHexString(b[i] & 0XFF);
			if (tmp.length() == 1) {
				sb.append("0" + tmp);
			} else {
				sb.append(tmp);
			}
		}
		return sb.toString();
	}

	/**
	 * 解密（不兼容IOS）
	 * @param src byte[]
	 * @param password String
	 * @return byte[]
	 * @throws Exception
	 */
	@Deprecated
	public static String decrypt(String datasource, String password)
			throws Exception {
		byte[] src = Base64.decode(datasource);
		// DES算法要求有一个可信任的随机数源
		SecureRandom random = new SecureRandom();
		// 创建一个DESKeySpec对象
		DESKeySpec desKey = new DESKeySpec(password.getBytes());
		// 创建一个密匙工厂
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(_keyType);
		// 将DESKeySpec对象转换成SecretKey对象
		SecretKey securekey = keyFactory.generateSecret(desKey);
		// Cipher对象实际完成解密操作
		Cipher cipher = Cipher.getInstance(_keyType);
		// 用密匙初始化Cipher对象
		cipher.init(Cipher.DECRYPT_MODE, securekey, random);
		// 真正开始解密操作
		return new String(cipher.doFinal(src), _charEn);
	}

}